package com.gzxw.mogublog.web.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gzxw.mogublog.base.global.BaseSysConf;
import com.gzxw.mogublog.base.holder.RequestHolder;
import com.gzxw.mogublog.commons.entity.*;
import com.gzxw.mogublog.commons.feign.PictureFeignClient;
import com.gzxw.mogublog.utils.R;
import com.gzxw.mogublog.utils.RedisUtil;
import com.gzxw.mogublog.utils.ResultUtil;
import com.gzxw.mogublog.utils.StringUtils;
import com.gzxw.mogublog.xo.service.*;
import com.gzxw.mogublog.xo.vo.CommentVO;
import com.gzxw.mogublog.xo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/web/comment")
@Slf4j
public class CommentController {

    @Autowired
    private CommentService commentService;

    @Autowired
    private UserService userService;

    @Autowired
    private PictureFeignClient pictureFeignClient;

    @Autowired
    private WebConfigService webConfigService;

    @Autowired
    private BlogService blogService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private RedisUtil redisUtil;


    @PostMapping("/getList")
    public R getList(@RequestBody CommentVO commentVO) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(commentVO.getBlogUid())) {
            queryWrapper.like("blog_uid", commentVO.getBlogUid());
        }
        queryWrapper.eq("source", commentVO.getSource());
        //分页
        Page<Comment> page = new Page<>();
        page.setCurrent(commentVO.getCurrentPage());
        page.setSize(commentVO.getPageSize());
        queryWrapper.eq("status", 1);
        queryWrapper.isNull("to_uid"); // 只取祖宗评论（特点：无to_uid）
        queryWrapper.orderByDesc("create_time");
        queryWrapper.eq("TYPE", "0");
        IPage<Comment> pageList = commentService.page(page, queryWrapper);
        List<Comment> list = pageList.getRecords();
        List<String> firstUidList = new ArrayList<>();
        list.forEach(item -> {
            firstUidList.add(item.getUid());
        });

        List<Comment> secondList = null;
        if (firstUidList.size() > 0) {
            // 取出所有的二级评论
            QueryWrapper<Comment> secondWrapper = new QueryWrapper<>();
            secondWrapper.eq("status", 1);
            secondWrapper.orderByAsc("create_time");
            secondWrapper.in("first_comment_uid", firstUidList);
            secondList = commentService.list(secondWrapper);
        }

        HashSet<String> userUidList = new HashSet<>();

        list.forEach(item -> {
            String userUid = item.getUserUid();
            String toUserUid = item.getToUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(item.getUserUid());
            }
            if (StringUtils.isNotEmpty(toUserUid)) {
                userUidList.add(item.getToUserUid());
            }
        });
        if (secondList != null) {
            secondList.forEach(item -> {
                String userUid = item.getUserUid();
                String toUserUid = item.getToUserUid();
                if (StringUtils.isNotEmpty(userUid)) {
                    userUidList.add(item.getUserUid());
                }
                if (StringUtils.isNotEmpty(toUserUid)) {
                    userUidList.add(item.getToUserUid());
                }
            });
        }

        Collection<User> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList);
        }

        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        userList.forEach(item -> {
            User user = new User();
            user.setAvatar(item.getAvatar());
            user.setUid(item.getUid());
            user.setNickName(item.getNickName());
            user.setUserTag(item.getUserTag());
            filterUserList.add(user);
        });

        List<String> fileUids = new ArrayList<>();
        filterUserList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                fileUids.add(item.getAvatar());
            }
        });
        String message = null;
        if (fileUids.size() > 0) {
            message = pictureFeignClient.getPictures(fileUids).getMessage();
        }
        List<File> picList = JSON.parseArray(message, File.class);

        Map<String, String> picMap = new HashMap<>();

        picList.forEach(item -> {
            picMap.put(item.getUid(), item.getPicUrl());
        });

        Map<String, User> userMap = new HashMap<>();

        filterUserList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar()) && picMap.get(item.getAvatar()) != null) {
                item.setPhotoUrl(picMap.get(item.getAvatar()));
            }
            userMap.put(item.getUid(), item);
        });

        // 给一级评论和二级评论设置User和ToUser
        list.forEach(item -> {
            // 设置本身的User
            item.setUser(userMap.get(item.getUserUid()));
            // 设置回复的User
            item.setToUser(userMap.get(item.getToUserUid()));
        });

        if (secondList != null) {
            secondList.forEach(item -> {
                item.setUser(userMap.get(item.getUserUid()));
                item.setToUser(userMap.get(item.getToUserUid()));
            });
        }

        // 组合一级评论和二级评论
        for (Comment parent : list) {
            List<Comment> children = new ArrayList<>();
            if (secondList != null) {
                for (Comment child : secondList) {
                    if (parent.getUid().equals(child.getFirstCommentUid())) {
                        children.add(child);
                    }
                }
                parent.setReplyList(children);
            }
        }
        pageList.setRecords(list);

        Map<String, Object> result = new HashMap<>();
        long total = pageList.getTotal();
        long size = pageList.getSize();
        long current = pageList.getCurrent();
        result.put("records", list);
        result.put("total", total);
        result.put("size", size);
        result.put("current", current);
        return R.success("200", result);
    }


    @PostMapping("/add")
    public R add(@RequestBody CommentVO commentVO) {

        HttpServletRequest request = RequestHolder.getRequest();

        if (request.getAttribute("user_uid") == null) {
            return R.error("500", "token令牌未被识别");
        }

        QueryWrapper<WebConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        WebConfig webConfig = webConfigService.getOne(queryWrapper);
        // 判断是否开启全局评论功能
        if ("0".equals(webConfig.getOpenComment())) {
            return R.error("500", "网站未开启评论功能");
        }

        if (StringUtils.isNotEmpty(commentVO.getBlogUid())) {
            Blog blog = blogService.getById(commentVO.getBlogUid());
            if ("0".equals(blog.getOpenComment())) {
                return R.error("500", "该博客未开启评论功能");
            }
        }

        String userUid = request.getAttribute("user_uid").toString();
        User user = userService.getById(userUid);

        // 判断字数是否超过限制
        if (commentVO.getContent().length() > 1024) {
            return R.error("500", "评论不能超过1024个字");
        }

        // 判断该用户是否被禁言
        if (user.getCommentStatus() == 0) {
            return R.error("500", "您没有发言权限");
        }

        String jsonResult = redisUtil.get("USER_PUBLISH_SPAM_COMMENT_COUNT" + BaseSysConf.REDIS_SEGMENTATION + userUid);
        if (!StringUtils.isEmpty(jsonResult)) {
            Integer count = Integer.valueOf(jsonResult);
            if (count >= 5) {
                return R.error("500", "由于发送过多无意义的评论，已被禁言一个小时~");
            }
        }

        // 判断是否垃圾评论
        String content = commentVO.getContent();
        if (StringUtils.isCommentSpam(content)) {
            if (StringUtils.isEmpty(jsonResult)) {
                Integer count = 0;
                redisUtil.setEx("USER_PUBLISH_SPAM_COMMENT_COUNT" + ":" + userUid, count.toString(), 1, TimeUnit.HOURS);
            } else {
                redisUtil.incrBy("USER_PUBLISH_SPAM_COMMENT_COUNT" + ":" + userUid, 1);
            }
            return R.error("500", "请输入有意义的评论~");
        }

        // 判断被评论的用户，是否开启了评论邮件的功能
        if (StringUtils.isNotEmpty(commentVO.getToUserUid())) {
            User toUser = userService.getById(commentVO.getToUserUid());
            // 若开启了邮件提醒
            if (toUser.getStartEmailNotification() == 1) {
                // 拿到被评论的那条评论
                Comment toComment = commentService.getById(commentVO.getToUid());
                if (toComment != null && StringUtils.isNotEmpty(toComment.getContent())) {
                    Map<String, String> map = new HashMap<>();
                    map.put("email", toUser.getEmail());
                    map.put("text", commentVO.getContent());
                    map.put("to_text", toComment.getContent());
                    map.put("nick_name", user.getNickName());
                    map.put("to_nickname", toUser.getNickName());
                    map.put("user_uid", toUser.getUid());

                    //TODO 发送评论邮件
                }
            }
        }

        Comment comment = new Comment();
        comment.setSource(commentVO.getSource());
        comment.setBlogUid(commentVO.getBlogUid());
        comment.setContent(commentVO.getContent());
        comment.setToUserUid(commentVO.getToUserUid());

        // 当评论不是一级评论时，需要设计一级评论UID字段
        if (StringUtils.isNotEmpty(commentVO.getToUid())) {
            Comment toComment = commentService.getById(commentVO.getToUid());
            // 表示 toComment是非一级评论
            if (toComment != null && StringUtils.isNotEmpty(toComment.getFirstCommentUid())) {
                comment.setFirstCommentUid(toComment.getFirstCommentUid());
            } else {
                // 表示父评论是一级评论，直接获取UID
                comment.setFirstCommentUid(toComment.getUid());
            }
        } else {
            // 当该评论是一级评论的时候，说明是对 博客详情、留言板、关于我
            // 判断是否开启邮件通知

        }

        comment.setUserUid(commentVO.getUserUid());
        comment.setToUid(commentVO.getToUid());
        comment.setStatus(1);
        comment.insert();

        // 如果是回复某人的评论，则向redis中写入该评论,count+1
        if (StringUtils.isNotEmpty(comment.getToUserUid())) {
            String redisKey = "USER_RECEIVE_COMMENT_COUNT"+":"+comment.getToUserUid();
            String count = redisUtil.get(redisKey);
            if (StringUtils.isNotEmpty(count)) {
                redisUtil.incrBy(redisKey,1);
            }else {
                redisUtil.setEx(redisKey,"1",7,TimeUnit.DAYS);
            }
        }

        return R.success("200", "评论成功");
    }


    @PostMapping("/getListByUser")
    public String getListByUser(HttpServletRequest request, @RequestBody UserVO userVO) {

        if (request.getAttribute("user_uid") == null) {
            return ResultUtil.result("error", "token令牌未被识别");
        }
        String requestUserUid = request.getAttribute("user_uid").toString();
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        //分页
        Page<Comment> page = new Page<>();
        page.setCurrent(userVO.getCurrentPage());
        page.setSize(userVO.getPageSize());
        queryWrapper.eq("TYPE", 0);
        queryWrapper.eq("status", 1);
        queryWrapper.orderByDesc("create_time");
        // 查找 我的评论 和 我的回复
        queryWrapper.and(wrapper -> wrapper.eq("user_uid", requestUserUid).or().eq("to_user_uid", requestUserUid));
        IPage<Comment> pageList = commentService.page(page, queryWrapper);
        List<Comment> list = pageList.getRecords();
        List<String> userUidList = new ArrayList<>();
        list.forEach(item -> {
            String userUid = item.getUserUid();
            String toUserUid = item.getToUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(userUid);
            }
            if (StringUtils.isNotEmpty(toUserUid)) {
                userUidList.add(toUserUid);
            }
        });

        // 获取用户列表
        Collection<User> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList);
        }
        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        userList.forEach(item -> {
            User user = new User();
            user.setAvatar(item.getAvatar());
            user.setUid(item.getUid());
            user.setNickName(item.getNickName());
            filterUserList.add(user);
        });
        // 获取用户头像
        List<String> fileList = new ArrayList<>();
        filterUserList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                fileList.add(item.getAvatar());
            }
        });

        String picureList = null;
        if (fileList.size() > 0) {
            picureList = pictureFeignClient.getPictures(fileList).getMessage();
        }
        List<File> picList = JSON.parseArray(picureList, File.class);
        Map<String, String> pictureMap = new HashMap<>();
        picList.forEach(item -> {
            pictureMap.put(item.getUid(),item.getPicUrl());
        });

        Map<String, User> userMap = new HashMap<>();
        userList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())&&pictureMap.get(item.getAvatar())==null) {
                item.setPhotoUrl(pictureMap.get(item.getAvatar()));
            }
            userMap.put(item.getUid(),item);
        });

        // 将评论分为 我的评论 和 我的回复
        List<Comment> commentList = new ArrayList<>();
        List<Comment> replyList = new ArrayList<>();

        list.forEach(item -> {

            if (StringUtils.isNotEmpty(item.getUserUid())) {
                item.setUser(userMap.get(item.getUserUid()));
            }
            if (StringUtils.isNotEmpty(item.getToUserUid())) {
                item.setToUser(userMap.get(item.getToUserUid()));
            }
            // 设置sourceName
            if (StringUtils.isNotEmpty(item.getSource())) {
                try {
                    item.setSourceName(item.getSource());
                } catch (Exception e) {
//                    log.error("ECommentSource转换异常");
                    log.info("ECommentSource转换异常");
                }
            }
            if (requestUserUid.equals(item.getUserUid())) {
                commentList.add(item);
            }
            if (requestUserUid.equals(item.getToUserUid())) {
                replyList.add(item);
            }
        });
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("commentList", commentList);
        resultMap.put("replyList", replyList);

        return ResultUtil.result("success",resultMap);
    }


    // 获取用户收到的评论回复数
    @GetMapping("/getUserReceiveCommentCount")
    public String getUserReceiveCommentCount(HttpServletRequest request) {
        log.info("获取用户收到的评论回复数");
        // 判断用户是否登录
        int commentCount = 0;
        if (request.getAttribute("user_uid")!=null) {
            String userUid = request.getAttribute("user_uid").toString();
            // 从redis中获取
            String redisKey = "USER_RECEIVE_COMMENT_COUNT"+":"+userUid;
            String count = redisUtil.get(redisKey);
            if (StringUtils.isNotEmpty(count)) {
                commentCount = Integer.parseInt(count);
            }
        }
        return ResultUtil.successWithData(commentCount);
    }

    // 阅读回复的评论
    @PostMapping("/readUserReceiveCommentCount")
    public String readUserReceiveCommentCount(HttpServletRequest request) {
        log.info("阅读用户接收的评论数");
        if (request.getAttribute("user_uid")!=null) {
            String userUid = request.getAttribute("user_uid").toString();
            String redisKey = "USER_RECEIVE_COMMENT_COUNT"+":"+userUid;
            redisUtil.delete(redisKey);
        }
        return ResultUtil.successWithMessage("阅读成功");
    }

}
